package util.Socket.pointSend;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class PointSendServer {
	 public void sendFile(){ 
		 int port=8821;
		try {
			ServerSocket server = new ServerSocket(port);

			Socket handle = server.accept();
			OutputStream out = handle.getOutputStream();
			InputStream in = handle.getInputStream();
			 final int orderLen = 1024;
			 byte[] orderArr = new byte[orderLen];
			 while (true) {
				  // 接收并解析指令
				// 等待client发送指令
				 int realOrderLen = in.read(orderArr, 0, orderLen);
				 if (realOrderLen < 0) {
				   break;
				 }
				 String orderStr = new String(orderArr, 0, realOrderLen);
				// 解析指令
				 String[] order = orderStr.trim().split("\\|"); // 这里是正则表达式，两斜线和一个竖线之间没有空格
				 final String filePath = order[0];
				 final int piece = Integer.parseInt(order[1]);
				 final int pieceSize = Integer.parseInt(order[2]);

				  // 通过指令读取指定文件中的指定块
				 byte[] buf = new byte[pieceSize]; // 缓冲区
				 FileInputStream f = new FileInputStream(filePath);
				 f.skip(piece * (long) pieceSize); // 跳转
				 int realBufLen = f.read(buf);  // 读取
				 f.close();
				  // 数据附上有效数据长度和MD5值
				// 获取md5值并将len转换成byte[]以通过socket传输
				 byte[] md5 = ByteMD5(buf);
				 byte[] lenInB = ByteBuffer.allocate(4).putInt(realBufLen).array();

				 // 合并，有效数据长度、数据的md5值、数据
				 ByteBuffer byteBuffer = ByteBuffer.allocate(lenInB.length + md5.length + buf.length);
				 byte[] result = byteBuffer.put(lenInB).put(md5).put(buf).array();
				  // 将数据发送给Client
				 out.write(result);
				}
				// 关闭连接
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    }  
	 
	 private static byte[] ByteMD5(byte[] data) {
		  try {
		      MessageDigest md = MessageDigest.getInstance("MD5");
		      md.update(data);
		      return md.digest();
		  } catch (NoSuchAlgorithmException e) {
		      return new byte[0];
		  }
		}
	 
	 public static void main(String[] args) {
		 new PointSendServer().sendFile();
	}
	 
}
